home *** CD-ROM | disk | FTP | other *** search
- /* Convert Triangulated Poly files (TPOLY object format)
- * to indexed polygons in the 3-D Object File Format (OFF)
- *
- * POLY2OFF by Jason Mathews
- * NASA/Goddard Space Flight Center
- * Greenbelt, MD 20771
- * e-mail: mathews@nssdca.gsfc.nasa.gov (Internet)
- *
- * usage: poly2off [max_number_polygons] < tpoly_infile > off_outfile
- *
- * Modification history:
- * 31-Mar-94 Original version (for unix platforms).
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <search.h>
-
- #define DEF_POLYS 10000 /* default # of polygons */
- #define MAXPTS 9000 /* maximal allowable data points */
- #define MAXEDGES 10000 /* maximal number of edges */
-
- /* types and structures */
-
- typedef unsigned int uint;
-
- typedef struct {
- float x, y, z;
- } Point;
-
- typedef struct {
- uint v1, v2;
- } Edge;
-
- int ptcmp( void* arg1, void* arg2 )
- {
- return memcmp(arg1, arg2, sizeof(Point));
- }
-
- int edgecmp( void* arg1, void* arg2 )
- {
- return memcmp(arg1, arg2, sizeof(Edge));
- }
-
- void usage()
- {
- fprintf(stderr, "Usage: poly2off [max_number_polygons]\n\n");
- fprintf(stderr, "Defaults: number of polygons = %u\n", DEF_POLYS);
- fprintf(stderr, "\t number of points = %u\n\n", MAXPTS);
- fprintf(stderr, "Example: poly2off < teapot.tpoly > teapot.off\n");
- exit(1);
- }
-
- void MakeEdge( Edge* e, uint v1, uint v2 )
- {
- if (v1 > v2)
- {
- uint tmp=v1; v1=v2; v2=tmp;
- }
- e->v1=v1; e->v2=v2;
- }
-
- int main( int argc, char** argv )
- {
- uint i, j;
- int npts;
- long nLines = 0;
- uint nPoints = 0;
- uint nPolygons = 0;
- uint nEdges = 0;
- uint maxPlanes = DEF_POLYS;
- uint** planes;
- Point points[MAXPTS];
- Edge edgeList[MAXEDGES];
-
- if (argc == 2)
- {
- maxPlanes = atoi(argv[1]);
- if (!maxPlanes) usage();
- }
-
- planes = (uint **) malloc( maxPlanes * sizeof(uint*));
- if (!planes)
- {
- perror("poly2off");
- return 1;
- }
-
- while (scanf("%d", &npts) == 1)
- {
- uint old_pt;
- if (npts <= 0)
- {
- fprintf(stderr, "error: invalid number of points at line %ld\n",
- nLines);
- break;
- }
- nLines++;
- planes[nPolygons] = (uint*) malloc( (npts+1) * sizeof(uint));
- if (!planes[nPolygons])
- {
- perror("poly2off");
- return 1;
- }
-
- /* the first element contains the # of verticies in the polygon */
- planes[nPolygons][0] = npts;
-
- for (i=1; i <= npts; i++)
- {
- Point pt;
- Point* result;
- size_t count = nPoints, idx;
-
- if (scanf("%f %f %f", &pt.x, &pt.y, &pt.z) != 3)
- {
- fprintf(stderr, "error: invalid points at line %ld\n", nLines);
- return 1;
- }
-
- result = (Point*) lsearch(&pt, points, &count,
- sizeof(Point), ptcmp);
-
- /* vertex index starts from 1, not 0 */
-
- if (count == nPoints)
- {
- idx = (uint) (result - points)+1; /* index of point */
- }
- else {
- /* new point added to table */
- if ((idx = ++nPoints) >= MAXPTS-1)
- {
- fprintf(stderr, "error: too many points\n\n");
- usage();
- }
- }
-
- planes[nPolygons][i] = idx;
- nLines++;
- } /* for */
-
- /* check edges formed by polygon */
- old_pt = planes[nPolygons][npts];
- for (i=1; nEdges < MAXEDGES && i <= npts; i++)
- {
- uint idx = planes[nPolygons][i];
- if (old_pt != idx)
- {
- Edge e;
- size_t count = nEdges;
- MakeEdge(&e, old_pt, idx);
- lsearch(&e, edgeList, &count, sizeof(Edge), edgecmp);
- if (count != nEdges) nEdges++; /* new edge added */
- }
- old_pt = idx;
- } /* for each point */
-
- if (++nPolygons > maxPlanes)
- {
- fprintf(stderr, "error: too many polygons: specify max parameter large enough\n\n");
- usage();
- }
- } /* while */
-
- /*
- * print object in Object File Format (OFF)
- */
-
- printf("%u %u %u\n", nPoints, nPolygons, nEdges);
- for (i=0; i < nPoints; i++)
- {
- printf("%g %g %g\n", points[i].x, points[i].y, points[i].z);
- }
-
- for (i=0; i < nPolygons; i++)
- {
- printf("%u", planes[i][0]);
- for (j=1; j <= planes[i][0]; j++)
- printf(" %u", planes[i][j]);
- printf("\n");
- }
-
- return 0; /* okay */
- }
-